package reflect;

import java.lang.reflect.Method;
import java.util.Scanner;

/*反射机制
反射是Java的动态机制，它允许我们程序在【运行期间】确定方法的调用，属性的操作，对象的实例化等
反射机制提高了代码的灵活度，但是运行效率较低，开销大，因此不能过度依赖

 */
public class ReflectDemo01 {
    public static void main(String[] args) throws ClassNotFoundException {
        /*
        使用反射机制的第一步，：获取要操作类的类对象
        Class类的示例
        Class的每一个实例用于表示jvm加载的一个类的相关信息
        并且每个被jvm加载的类【有且只有一个】类对象与之对应
        通过获取一个类的类对象，我们可以了解其对应类的一切内容：类名，包信息，构造其信息，方法信息
        从而在程序运行期间进行相关操作
        如何获取一个类的类对象
        1：类名.class
        例如：
        Class cla = String.class //获取String的类对象
        Class cla = int.Class //获取int类型的类对象，注意：基本类型仅有这一种方法获取
        2、对象.getClass（）
        3、Class.forName（String className）
        如：
        Class cla = Class.forName("java.lang.String")
        根据类名获取它的类对象，类名必须是完全限定名 即：包名.类名
        4、后期还可以使用类加载器ClassLoader做更高阶操作
         */
        //通过对象获取其表示的类的完全限定名
        //Class cla = String.class;
        //Class cla = ArrayList.class;
        //指定类的完全限定名方式获取一个类对象
        //Class cla = Class.forName("java.lang.String");
        //Class cla = Class.forName("java.util.ArrayList");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个类名");
        String s = scanner.nextLine();
        Class cla = Class.forName(s);
        //获取类名
        String name = cla.getSimpleName();
        System.out.println(name);
        /*通过类对象的方法
        package getPackage
        可以获取当前类对象所表示的包的信息，每个包信息用一个package对象表示
        package也是反射对象之一，它的每一个实例用于表示每一个包信息
         */
        Package pack = cla.getPackage();
        //通过包对象获取对应的包名
        String name1 = pack.getName();
        System.out.println(name1);
        //method[] getmethods()
        //该方法可以获取当前类对象所表示的类中的所有公开方法
        Method[] methods = cla.getMethods();
        System.out.println("String的方法个数有" + methods.length + "个");
        for (Method method: methods) {
            System.out.println(method.getName());
        }
    }
}
